/**
 @file earth2wireframe.c

 @brief Convert Earth wireframe in Lon, Lat pairs into X,Y,Z integer fixed point
 Each group (a set of Lon, Lat pairs) is separated by one or 
 more blank lines, # are comments and ignored

 @par Copyright &copy; 2015 Mike Gore, GPL License
 @par You are free to use this code under the terms of GPL
   please retain a copy of this notice in any code you use it in.

This is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version.

This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <unistd.h>
#include <libgen.h>


#define TEST
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef int int32_t;

#define MEMSPACE /**/
#include "../wire/wire_types.h"
#include "../cordic/cordic2c_inc.h"
#include "../cordic/cordic.h"

/// @brief Convert of Radians
/// @param[in] deg: degrees
/// @return radians
double deg2rad(double  deg)
{
	return (deg * 0.0174532925);
}

/// @brief Get the current date in a string
/// @return void
char *get_date()
{
    int len;
    char *ptr;
    time_t timev;
	timev = time(0);
	ptr = asctime(localtime(&timev));
    len = strlen(ptr);
    ptr[len-1] = 0;
    return(ptr);
}


/// @brief Convert earth wireframe data to C structure
///		Usage: %s -f source -o result\n",argv[0]);
///		-f source is the lot,lat dataset pairs
///		-o result is the con=verted file into CORDIC fixed point format
int main(int argc, char *argv[])
{
	double xx,yy,zz;
	double scale;
	double lat,lon;
	double lat_rad,lon_rad;
	short int x,y,z;
	int i;
	int len;
	int prototype = 1;
	char *p, *name, *oname;
	FILE *FI,*FO;
	char buff[256];
	char datestr[256];

	char cwd[512];

	name = NULL;

	getcwd(cwd, 510);

	for(i=1; i<argc;++i)
	{
		p = argv[i];
		if(*p != '-')
			continue;
		++p;
		if(*p == 'f')
		{
			name = argv[++i];
		}
		if(*p == 'o')
		{
			oname = argv[++i];
		}
	}
	if(!name || !oname)
	{
		fprintf(stderr,"Usage: %s -f filename [-p]\n",argv[0]);
		fprintf(stderr,"-f filename is the lot,lat dataset pairs\n");
		exit(1);
	}
	if(strcmp(name,oname) == 0)
	{
		fprintf(stderr,"sorce and destination file can not be the same\n");
		exit(1);
	}
	FI = fopen(name,"r");
	if(FI == NULL)
	{
		fprintf(stderr,"Can not open: [%s]\n", name);
		exit (1);
	}

	FO = fopen(oname,"w");
	if(FO == NULL)
	{
		fprintf(stderr,"Can not open: [%s]\n", oname);
		exit (1);
	}
	fprintf(FO,"#ifndef _EARTH_DATA_H_\n");
	fprintf(FO,"#define _EARTH_DATA_H_\n");
	fprintf(FO,"/**\n");
	fprintf(FO," @file %s\n", basename(oname));
	fprintf(FO," Generated by:[%s/%s]\n", cwd, basename(argv[0]));
	fprintf(FO," On: %s\n", get_date());
	fprintf(FO," By Mike Gore 2015, Earth Wireframe C Table\n");
	fprintf(FO," Source: %s\n", name);
	fprintf(FO,"*/\n");

	fprintf(FO,"MEMSPACE_RO wire_p earth_data[] = {\n");

	FI = fopen(name,"r");
	if(FI == NULL)
	{
		fprintf(stderr,"Can not open: [%s]\n", name);
		exit (1);
	}

	while( fgets(buff, sizeof(buff)-2, FI))
    {
		len = strlen(buff);	
		// remove any white space characters at the end of the line
		while(len && buff[len-1] < ' ')
			buff[--len] = 0;

		if(!len)
		{
			if(lon == WIRE_SEP)
				continue;
		}
		if(*buff == '#')
		{
			if(lon == WIRE_SEP)
				continue;
			fprintf(FO,"/* %s */\n", buff);
		}

		lon = WIRE_SEP;
		lat = WIRE_SEP;
		
		// degrees
		if(len)
			sscanf(buff, "%lf %lf", &lon, &lat);

        // radians
        lon_rad = deg2rad(lon);
        lat_rad = deg2rad(lat);

        //printf("%f, %f\n", lon,lat);
        //printf("%f, %f\n", lon_rad,lat_rad);
        //fflush(stdout);

        if(!len || lon == WIRE_SEP || lat == WIRE_SEP)
        {
            // this point is the end of a vector - not plotted
            x = WIRE_SEP;
            y = WIRE_SEP;
            z = WIRE_SEP;
           	fprintf(FO,"\t{%d,%d,%d}, /* sep */\n", 
				(int)x ,(int)y ,(int)z 
				);
            //printf("\t{%f,%f,%f},\n", x,y,z);
        }
        else
        {
			// WIRE_HALF gives scale factor of 1 (+/-0.5)
			x = (cos(lat_rad) * cos(lon_rad)) * WIRE_HALF;
            y = (cos(lat_rad) * sin(lon_rad)) * WIRE_HALF;
            z = sin(lat_rad) * WIRE_HALF;
            // reverse is
            // lat = asin(z / R)
            // lon = atan2(y, x)
           	fprintf(FO,"\t{%d,%d,%d}, /* %f, %f */\n", 
				(int)x ,(int)y ,(int)z ,
				lon, lat);
            //printf("\t{%f,%f,%f},\n", x,y,z);
        }
    }
	fclose(FI);
    // this point is the end of a vector - not plotted
    x = WIRE_SEP;
    y = WIRE_SEP;
    z = WIRE_SEP;
	fprintf(FO,"\t{%d,%d,%d}, /* sep */\n", 
		(int)x ,(int)y ,(int)z 
		);
    // this point is the end of the data set
    x = WIRE_END;
    y = WIRE_END;
    z = WIRE_END;
	fprintf(FO,"\t{%d,%d,%d}, /* END */\n", 
		(int)x ,(int)y ,(int)z 
		);
   	fprintf(FO,"};\n");
	fprintf(FO,"#else /* _EARTH_DATA_H */\n");
	fprintf(FO,"	extern MEMSPACE_RO wire_p earth_data[];\n");
	fprintf(FO,"#endif /* _EARTH_DATA_H_ */\n");
	fclose(FO);
	return(0);
}

